home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #1 / Amiga Plus 1999 #1.iso / System-Boost / Sound / Euterpe / Developer / bnkdemo.c next >
Encoding:
C/C++ Source or Header  |  1998-06-18  |  33.8 KB  |  1,129 lines

  1. /* BNKDEMO
  2.  * An example for an BANKEDITOR xapp application
  3.  * This is an editor for the Roland MT32
  4.  * Author : Dominique Lorre
  5.  * $Id$
  6.  */
  7.  
  8. #include "bnkdemo.h"
  9.  
  10. VOID main(VOID)
  11. {
  12. int retval ;
  13.  
  14.     if (InitAll()) {
  15.         ProcessEvents() ;
  16.         retval =  CloseAll(0)?RETURN_OK:RETURN_FAIL;
  17.     }
  18.     else
  19.         retval = RETURN_FAIL ;
  20.     exit(retval) ;
  21. }
  22.  
  23. /****** bnkdemo.c/InitAll **************************************************
  24. *
  25. *   NAME
  26. *   InitAll -- Main Initializations
  27. *
  28. *   SYNOPSIS
  29. *   success = InitAll()
  30. *   BOOL InitAll(void)
  31. *
  32. *   FUNCTION
  33. *       InitAll allocates all needed resources step by step and is responsible
  34. *       for the initialization of the communication with Euterpe. CloseAll will
  35. *       be called in case of failure.
  36. *
  37. *   INPUTS
  38. *       None
  39. *
  40. *   RESULTS
  41. *       success     TRUE if the initialization succeed, FALSE if not
  42. *
  43. *   BUGS
  44. *       This function has a weak point because it may fail if Euterpe is closing
  45. *       when this task is loading. Forbid()/Permit() might solve the problem.
  46. *       Anyway, under normal use effects will not be loaded when Euterpe is
  47. *       exiting and developers have been asked not to use Forbid(). If
  48. *       someone has an idea...
  49. *
  50. *   SEE ALSO
  51. *       fxdemo.c/CloseAll
  52. ****************************************************************************
  53. *
  54. */
  55. BOOL InitAll(void)
  56. {
  57. WORD i, j, k ;
  58.     // First, create a ReplyPort for communication with Euterpe
  59.  
  60.     replyPort = CreateMsgPort() ;
  61.     if (!replyPort)
  62.         return CloseAll(1) ;
  63.  
  64.     // Now, initialize the Message
  65.  
  66.     if (xmsg = (struct XAppMsg *)AllocVec(sizeof(struct XAppMsg), MEMF_CLEAR|MEMF_PUBLIC)) {
  67.         xmsg->xm_Message.mn_Node.ln_Type = NT_MESSAGE ;
  68.         xmsg->xm_Message.mn_Length = sizeof( struct XAppMsg ) ;
  69.         xmsg->xm_Message.mn_ReplyPort = replyPort ;
  70.     }
  71.     else
  72.         return CloseAll(2) ;
  73.  
  74.  
  75.     // Parameters initialization
  76.     bData.bd_UnitNumber = 16 ;
  77.     bData.bd_ToneNumber = 0 ;
  78.     bData.bd_ProgramNumber = 0 ;
  79.     bData.bd_PartNumber = 0 ;
  80.     bData.bd_PartialNumber = 0 ;
  81.     bData.bd_ParamNumber = 0 ;
  82.  
  83.     for (i=0; i<64; i++) {
  84.         strcpy(bData.bd_Tone[i].to_Name, "UnNamed") ;
  85.         bData.bd_Tone[i].to_P12 = 0 ;
  86.         bData.bd_Tone[i].to_P34 = 0 ;
  87.         bData.bd_Tone[i].to_PMute= 0 ;
  88.         bData.bd_Tone[i].to_EnvMode = 0 ;
  89.         for (j=0; j<4; j++) {
  90.             for (k=0; k<58; k++)
  91.                 bData.bd_Tone[i].to_Partial[j][k] = 0 ;
  92.         }
  93.     }
  94.  
  95.     // Look at Euterpe's xapp port
  96.  
  97.     if (XAppPort = FindPort((UBYTE *)XAPPPORTNAME)) {
  98.         // Euterpe is here, let's register
  99.         xmsg->xm_Action = XAPPACT_ADD ;
  100.         xmsg->xm_Tags = ti ;
  101.         PutMsg(XAppPort, (struct Message *)xmsg);
  102.         WaitPort(replyPort) ;
  103.         replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  104.         // Euterpe has given us a name for our port
  105.         xHandle = replymsg->xm_Result ;
  106.         if (!xHandle)
  107.             return CloseAll(3) ;
  108.         th[0].ti_Data = td[0].ti_Data = rd[0].ti_Data = (ULONG)xHandle ;
  109.         td[1].ti_Data = rd[1].ti_Data = (ULONG)midibuffer ;
  110.     }
  111.     else
  112.         return CloseAll(3) ;
  113.  
  114.     // Now, create our Port with the name given by Euterpe
  115.  
  116.     MyPort = CreatePort(MyPortName, NULL);
  117.  
  118.     // We are ready now, tell Euterpe how the init was
  119.  
  120.     xmsg->xm_Action = MyPort ? XAPPACT_INIT : XAPPACT_FAILURE ;
  121.     xmsg->xm_Tags = th ;
  122.     PutMsg(XAppPort, (struct Message *)xmsg);
  123.     WaitPort(replyPort) ;
  124.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  125.  
  126.     if (!MyPort)
  127.         return CloseAll(4) ;
  128.  
  129.      msig = 1 << MyPort->mp_SigBit ;
  130.  
  131.      // A bank editor should open its window on startup
  132.      if (InitWin())
  133.         winopen = TRUE ;
  134.  
  135.      return TRUE ;
  136. }
  137. /****** bnkdemo.c/CloseAll *************************************************
  138. *
  139. *   NAME
  140. *   CloseAll -- Deallocates the resources
  141. *
  142. *   SYNOPSIS
  143. *   success = CloseAll(level)
  144. *   BOOL CloseAll(WORD)
  145. *
  146. *   FUNCTION
  147. *       CloseAll() will deallocate all the successfully allocated resources
  148. *
  149. *   INPUTS
  150. *       level   0 if normal deallocation or the step where allocation failed
  151. *
  152. *   RESULTS
  153. *       success TRUE if called with level=0 FALSE in other cases
  154. *
  155. ****************************************************************************
  156. *
  157. */
  158.  
  159. BOOL CloseAll(WORD level)
  160. {
  161.     switch(level) {
  162.         case 0:
  163.             DeletePort(MyPort) ;
  164.         case 4:
  165.         case 3:
  166.             FreeVec(xmsg) ;
  167.         case 2:
  168.             DeleteMsgPort(replyPort) ;
  169.     }
  170.     return (BOOL) ( level ? FALSE : TRUE ) ;
  171. }
  172.  
  173. void ProcessEvents(void)
  174. {
  175. ULONG           sigmask ;
  176. BOOL            end ;
  177. enum XAppAction action ;
  178.  
  179.     end = FALSE ;
  180.     winopen = TRUE ;
  181.  
  182.     while (!end) {
  183.         sigmask = msig ;
  184.         if (winopen) sigmask |= winsig ;
  185.         signal = Wait(sigmask) ;
  186.         if (signal & winsig) {
  187.             // A better way of doing this could be to place the semaphore
  188.             // calls at the beginning of each modification of the bData fields
  189.             ProcessWinEvents() ;
  190.             if (!winopen)
  191.                 CloseWin(0) ;
  192.         }
  193.         if (signal & msig) {
  194.             while (emsg = (struct XAppMsg *)GetMsg(MyPort)) {
  195.                 action = emsg->xm_Action ;
  196.                 switch (action) {   // processing BEFORE ReplyMsg
  197.                 case XAPPACT_SHOW:
  198.                 case XAPPACT_HIDE:
  199.                 case XAPPACT_REMOVE:
  200.                     emsg->xm_Error = XAPPERR_OK ;   // fine
  201.                     break ;
  202.                 case XAPPACT_PROGRAMLIST:
  203.                     GetProgramList() ;
  204.                     emsg->xm_Error = XAPPERR_OK ;   // fine
  205.                     break ;
  206.                 default:
  207.                     emsg->xm_Error = XAPPERR_ACTION_NOT_KNOWN ;
  208.                     break ;
  209.                 }
  210.                 // Do not reply to a remove msg
  211.                 // since Euterpe does not wait for it
  212.                 if (action != XAPPACT_REMOVE)
  213.                     ReplyMsg((struct Message *)emsg) ;
  214.                 switch (action) {   // processing AFTER ReplyMsg
  215.                     case XAPPACT_SHOW:
  216.                         if (!winopen && InitWin())
  217.                             winopen = TRUE ;
  218.                         break ;
  219.                     case XAPPACT_REMOVE:
  220.                         end = TRUE ;
  221.                     case XAPPACT_HIDE:
  222.                         if (winopen) {
  223.                             CloseWin(0) ;
  224.                         }
  225.                         break ;
  226.                 }
  227.             }
  228.         }
  229.     }
  230. }
  231.  
  232. LONG __saveds PartialParameter(struct Gadget *g,  WORD level)
  233. {
  234.     return (LONG)partial[level] ;
  235. }
  236.  
  237. BOOL InitWin(void)
  238. {
  239. struct NewGadget ng ;
  240. struct TextExtent te ;
  241. UWORD winZoom[4] = { 50, 50, 300, 20 } ;
  242. WORD    maxpartialname, i ;
  243. char    *unstr = "Unit : %ld" ;
  244. char    *prgstr = "Program : %ld" ;
  245. char    *tostr = "Tone : %ld" ;
  246. char    *partstr = "Part : %ld" ;
  247. char    *partialstr = "Partial : %ld" ;
  248. char    *paramstr = "%21s" ;
  249. char    *valstr = "Value : %ld" ;
  250. char    *sp1str = "Partials 1 & 2 : %ld" ;
  251. char    *sp2str = "Partials 3 & 4 : %ld" ;
  252.  
  253.  
  254.  
  255.     ps = LockPubScreen((UBYTE *)"Euterpe") ; // Get the Euterpe public screen
  256.     if (!ps)
  257.         return CloseWin(1) ;
  258.  
  259.     maxpartialname = 0 ;
  260.     for (i=0; i<58; i++) {
  261.         TextExtent(&ps->RastPort, partial[i],
  262.             strlen(partial[i]), &te) ;
  263.         maxpartialname = MAX(maxpartialname, te.te_Width) ;
  264.  
  265.     }
  266.     winZoom[0] = winZoom[3] = ps->BarHeight ;  // cosmetic details
  267.  
  268.     vi = GetVisualInfo(ps, NULL) ;
  269.     if (!vi)
  270.         return CloseWin(2) ;
  271.  
  272.     glist = NULL ;
  273.     gad = CreateContext(&glist) ;
  274.     if (!gad)
  275.         return CloseWin(3) ;
  276.  
  277.     ng.ng_VisualInfo = vi ;
  278.     ng.ng_TextAttr = ps->Font ;
  279.  
  280.     ng.ng_GadgetText = (UBYTE *)"Upload" ;
  281.     TextExtent(&ps->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText), &te) ;
  282.     ng.ng_TopEdge = ps->BarHeight + 8 ; // font adaptative method
  283.     ng.ng_LeftEdge =  20 ;
  284.     ng.ng_Width = te.te_Width + 8 ;
  285.     ng.ng_Height = ng.ng_TextAttr->ta_YSize * 3 / 2 ;
  286.     ng.ng_GadgetID = UPLOAD_ID ;
  287.     ng.ng_Flags = PLACETEXT_IN ;
  288.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(BUTTON_KIND, gad, &ng,
  289.         TAG_DONE);
  290.  
  291.     if (!gad)
  292.         return CloseWin(4);
  293.  
  294.  
  295.     ng.ng_GadgetText = (UBYTE *)"DownLoad" ;
  296.     TextExtent(&ps->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText), &te) ;
  297.     ng.ng_TopEdge = ps->BarHeight + 8 ; // font adaptative method
  298.     ng.ng_LeftEdge =  ng.ng_LeftEdge + ng.ng_Width + 8 ;
  299.     ng.ng_Width = te.te_Width + 8 ;
  300.     ng.ng_GadgetID = DOWNLOAD_ID ;
  301.     ng.ng_Flags = PLACETEXT_IN ;
  302.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(BUTTON_KIND, gad, &ng,
  303.         TAG_DONE);
  304.  
  305.     if (!gad)
  306.         return CloseWin(4);
  307.  
  308.     ng.ng_GadgetText = (UBYTE *)"Load" ;
  309.     TextExtent(&ps->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText), &te) ;
  310.     ng.ng_TopEdge = ps->BarHeight + 8 ; // font adaptative method
  311.     ng.ng_LeftEdge =  ng.ng_LeftEdge + ng.ng_Width + 8 ;
  312.     ng.ng_Width = te.te_Width + 8 ;
  313.     ng.ng_GadgetID = LOAD_ID ;
  314.     ng.ng_Flags = PLACETEXT_IN ;
  315.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(BUTTON_KIND, gad, &ng,
  316.         TAG_DONE);
  317.  
  318.     if (!gad)
  319.         return CloseWin(4);
  320.  
  321.     ng.ng_GadgetText = (UBYTE *)"Save" ;
  322.     TextExtent(&ps->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText), &te) ;
  323.     ng.ng_TopEdge = ps->BarHeight + 8 ; // font adaptative method
  324.     ng.ng_LeftEdge =  ng.ng_LeftEdge + ng.ng_Width + 8 ;
  325.     ng.ng_Width = te.te_Width + 8 ;
  326.     ng.ng_GadgetID = SAVE_ID ;
  327.     ng.ng_Flags = PLACETEXT_IN ;
  328.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(BUTTON_KIND, gad, &ng,
  329.         TAG_DONE);
  330.  
  331.     if (!gad)
  332.         return CloseWin(4);
  333.  
  334.     ng.ng_GadgetText = (UBYTE *)"Set Part" ;
  335.     TextExtent(&ps->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText), &te) ;
  336.     ng.ng_TopEdge = ps->BarHeight + 8 ; // font adaptative method
  337.     ng.ng_LeftEdge =  ng.ng_LeftEdge + ng.ng_Width + 8 ;
  338.     ng.ng_Width = te.te_Width + 8 ;
  339.     ng.ng_GadgetID = SETPART_ID ;
  340.     ng.ng_Flags = PLACETEXT_IN ;
  341.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(BUTTON_KIND, gad, &ng,
  342.         TAG_DONE);
  343.  
  344.     if (!gad)
  345.         return CloseWin(4);
  346.  
  347.     ng.ng_GadgetText = (UBYTE *)"Set Program" ;
  348.     TextExtent(&ps->RastPort, ng.ng_GadgetText, strlen(ng.ng_GadgetText), &te) ;
  349.     ng.ng_TopEdge = ps->BarHeight + 8 ; // font adaptative method
  350.     ng.ng_LeftEdge =  ng.ng_LeftEdge + ng.ng_Width + 8 ;
  351.     ng.ng_Width = te.te_Width + 8 ;
  352.     ng.ng_GadgetID = SETPRG_ID ;
  353.     ng.ng_Flags = PLACETEXT_IN ;
  354.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(BUTTON_KIND, gad, &ng,
  355.         TAG_DONE);
  356.  
  357.     if (!gad)
  358.         return CloseWin(4);
  359.  
  360.     ng.ng_LeftEdge =  ng.ng_LeftEdge + ng.ng_Width + 8 ;
  361.     ng.ng_Width = 128 ;
  362.     ng.ng_GadgetID = UNIT_ID ;
  363.     ng.ng_Flags = PLACETEXT_RIGHT ;
  364.     ng.ng_GadgetText = NULL ;
  365.  
  366.  
  367.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  368.     GTSL_Min,           1,
  369.     GTSL_Max,           32,
  370.     GTSL_Level,         bData.bd_UnitNumber+1,
  371.     GTSL_LevelFormat,   unstr,
  372.     GTSL_MaxLevelLen,   20,
  373.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  374.     GA_RelVerify,       TRUE,
  375.     TAG_DONE);
  376.     if (!gad)
  377.         return CloseWin(4);
  378.  
  379.     ng.ng_TopEdge += ng.ng_Height + 8 ;
  380.     ng.ng_LeftEdge =  20 ;
  381.     ng.ng_Width = 128 ;
  382.     ng.ng_GadgetID = PROGRAM_ID ;
  383.     ng.ng_Flags = PLACETEXT_RIGHT ;
  384.     ng.ng_GadgetText = NULL ;
  385.  
  386.  
  387.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  388.     GTSL_Min,           1,
  389.     GTSL_Max,           128,
  390.     GTSL_Level,         bData.bd_ProgramNumber+1,
  391.     GTSL_LevelFormat,   prgstr,
  392.     GTSL_MaxLevelLen,   20,
  393.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  394.     GA_RelVerify,       TRUE,
  395.     TAG_DONE);
  396.     if (!gad)
  397.         return CloseWin(4);
  398.  
  399.     ng.ng_LeftEdge =  300 ;
  400.     ng.ng_Width = 128 ;
  401.     ng.ng_GadgetID = PART_ID ;
  402.     ng.ng_Flags = PLACETEXT_RIGHT ;
  403.  
  404.  
  405.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  406.     GTSL_Min,           1,
  407.     GTSL_Max,           8,
  408.     GTSL_Level,         bData.bd_PartNumber+1,
  409.     GTSL_LevelFormat,   partstr,
  410.     GTSL_MaxLevelLen,   20,
  411.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  412.     GA_RelVerify,       TRUE,
  413.     TAG_DONE);
  414.     if (!gad)
  415.         return CloseWin(4);
  416.  
  417.     ng.ng_TopEdge += ng.ng_Height + 8 ;
  418.     ng.ng_LeftEdge =  20 ;
  419.     ng.ng_Width = 128 ;
  420.     ng.ng_GadgetID = TONE_ID ;
  421.     ng.ng_Flags = PLACETEXT_RIGHT ;
  422.  
  423.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  424.     GTSL_Min,           1,
  425.     GTSL_Max,           64,
  426.     GTSL_Level,         bData.bd_ToneNumber+1,
  427.     GTSL_LevelFormat,   tostr,
  428.     GTSL_MaxLevelLen,   20,
  429.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  430.     GA_RelVerify,       TRUE,
  431.     TAG_DONE);
  432.     if (!gad)
  433.         return CloseWin(4);
  434.  
  435.     ng.ng_LeftEdge =  300 ;
  436.     ng.ng_Width = 128 ;
  437.     ng.ng_GadgetID = TONENAME_ID ;
  438.     ng.ng_Flags = PLACETEXT_RIGHT ;
  439.     strncpy(tonename, bData.bd_Tone[bData.bd_ToneNumber].to_Name, 10) ;
  440.     tonename[10] = '\0' ;
  441.  
  442.  
  443.     ng.ng_GadgetText = (UBYTE *)"Tone Name" ;
  444.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(STRING_KIND, gad, &ng,
  445.     GTST_String,        tonename,
  446.     GTST_MaxChars,      10,
  447.     TAG_DONE);
  448.     if (!gad)
  449.         return CloseWin(4);
  450.  
  451.     ng.ng_TopEdge += ng.ng_Height + 8 ;
  452.     ng.ng_LeftEdge =  20 ;
  453.     ng.ng_Width = 128 ;
  454.     ng.ng_GadgetID = SPARTIAL1_ID ;
  455.     ng.ng_Flags = PLACETEXT_RIGHT ;
  456.     ng.ng_GadgetText = NULL ;
  457.  
  458.  
  459.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  460.     GTSL_Min,           0,
  461.     GTSL_Max,           12,
  462.     GTSL_Level,         bData.bd_Tone[bData.bd_ToneNumber].to_P12,
  463.     GTSL_LevelFormat,   sp1str,
  464.     GTSL_MaxLevelLen,   strlen(sp1str),
  465.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  466.     GA_RelVerify,       TRUE,
  467.     TAG_DONE);
  468.     if (!gad)
  469.         return CloseWin(4);
  470.  
  471.     ng.ng_LeftEdge =  300 ;
  472.     ng.ng_Width = 128 ;
  473.     ng.ng_GadgetID = SPARTIAL2_ID ;
  474.     ng.ng_Flags = PLACETEXT_RIGHT ;
  475.  
  476.  
  477.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  478.     GTSL_Min,           0,
  479.     GTSL_Max,           12,
  480.     GTSL_Level,         bData.bd_Tone[bData.bd_ToneNumber].to_P34,
  481.     GTSL_LevelFormat,   sp2str,
  482.     GTSL_MaxLevelLen,   strlen(sp2str),
  483.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  484.     GA_RelVerify,       TRUE,
  485.     TAG_DONE);
  486.     if (!gad)
  487.         return CloseWin(4);
  488.  
  489.     ng.ng_TopEdge += ng.ng_Height + 8 ;
  490.     ng.ng_LeftEdge =  20 ;
  491.     ng.ng_Width = 128 ;
  492.     ng.ng_GadgetID = ENVMODE_ID ;
  493.     ng.ng_Flags = PLACETEXT_RIGHT ;
  494.     ng.ng_GadgetText = "ENV MODE (Sustain)" ;
  495.  
  496.  
  497.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(CHECKBOX_KIND, gad, &ng,
  498.     GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_EnvMode,
  499.     TAG_DONE);
  500.     if (!gad)
  501.         return CloseWin(4);
  502.  
  503.  
  504.     ng.ng_TopEdge += ng.ng_Height + 8 ;
  505.     ng.ng_LeftEdge =  20 ;
  506.     ng.ng_Width = 128 ;
  507.     ng.ng_GadgetID = PARTIAL_ID ;
  508.     ng.ng_Flags = PLACETEXT_RIGHT ;
  509.     ng.ng_GadgetText = NULL ;
  510.  
  511.  
  512.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  513.     GTSL_Min,           1,
  514.     GTSL_Max,           4,
  515.     GTSL_Level,         bData.bd_PartialNumber+1,
  516.     GTSL_LevelFormat,   partialstr,
  517.     GTSL_MaxLevelLen,   strlen(partialstr),
  518.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  519.     GA_RelVerify,       TRUE,
  520.     TAG_DONE);
  521.     if (!gad)
  522.         return CloseWin(4);
  523.  
  524.     ng.ng_LeftEdge =  300 ;
  525.     ng.ng_Width = 128 ;
  526.     ng.ng_GadgetID = PARTIALMUTE_ID ;
  527.     ng.ng_Flags = PLACETEXT_RIGHT ;
  528.     ng.ng_GadgetText = "Use Partial" ;
  529.  
  530.  
  531.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(CHECKBOX_KIND, gad, &ng,
  532.     GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_PMute & (1 << bData.bd_PartialNumber),
  533.     TAG_DONE);
  534.     if (!gad)
  535.         return CloseWin(4);
  536.  
  537.     TextExtent(&ps->RastPort, paramstr, strlen(paramstr), &te) ;
  538.     ng.ng_TopEdge += ng.ng_Height + 8 ;
  539.     ng.ng_LeftEdge =  20 ;
  540.     ng.ng_Width = 128 ;
  541.     ng.ng_GadgetID = PARAMETER_ID ;
  542.     ng.ng_Flags = PLACETEXT_RIGHT ;
  543.     ng.ng_GadgetText = NULL ;
  544.  
  545.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  546.     GTSL_Min,           0,
  547.     GTSL_Max,           57,
  548.     GTSL_Level,         bData.bd_ParamNumber,
  549.     GTSL_LevelFormat,   paramstr,
  550.     GTSL_DispFunc,      PartialParameter,
  551.     GTSL_MaxLevelLen,   strlen(paramstr)+21,
  552.     GTSL_MaxPixelLen,   maxpartialname+te.te_Width+8,
  553.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  554.     GA_RelVerify,       TRUE,
  555.     TAG_DONE);
  556.     if (!gad)
  557.         return CloseWin(4);
  558.  
  559.     TextExtent(&ps->RastPort, valstr, strlen(valstr), &te) ;
  560.     ng.ng_LeftEdge =  300 ;
  561.     ng.ng_Width = 128 ;
  562.     ng.ng_GadgetID = VALUE_ID ;
  563.     ng.ng_Flags = PLACETEXT_RIGHT ;
  564.  
  565.  
  566.     gad  = tabgad[ng.ng_GadgetID] = CreateGadget(SLIDER_KIND, gad, &ng,
  567.     GTSL_Min,           minpartial[bData.bd_ParamNumber],
  568.     GTSL_Max,           maxpartial[bData.bd_ParamNumber],
  569.     GTSL_Level,         bData.bd_Tone[bData.bd_ToneNumber].to_Partial[bData.bd_PartialNumber][bData.bd_ParamNumber],
  570.     GTSL_LevelFormat,   valstr,
  571.     GTSL_MaxLevelLen,   strlen(valstr),
  572.     GTSL_LevelPlace,    PLACETEXT_RIGHT,
  573.     GA_RelVerify,       TRUE,
  574.     TAG_DONE);
  575.     if (!gad)
  576.         return CloseWin(4);
  577.  
  578.  
  579.     /* Open a simple window */
  580.     xappwin = OpenWindowTags(NULL,
  581.     WA_Left,            20,
  582.     WA_Top,             ps->BarHeight,
  583.     WA_Width,           620,
  584.     WA_Height,          ng.ng_TopEdge + ng.ng_Height + 8, // font adaptative
  585.     WA_Title,           MyPortName,
  586.     WA_CloseGadget,     TRUE,
  587.     WA_DepthGadget,     TRUE,
  588.     WA_Gadgets,         glist,
  589.     WA_IDCMP,           IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
  590.                         CHECKBOXIDCMP|SLIDERIDCMP|BUTTONIDCMP|STRINGIDCMP,
  591.     WA_DragBar,         TRUE,
  592.     WA_Activate,        TRUE,
  593.     WA_PubScreen,       ps,
  594.     WA_Zoom,            winZoom,
  595.     TAG_DONE) ;
  596.  
  597.     if (xappwin) {
  598.         GT_RefreshWindow(xappwin, NULL) ;
  599.         winsig = 1 << xappwin->UserPort->mp_SigBit ;
  600.         return TRUE ;
  601.     }
  602.     else
  603.         return CloseWin(5) ;
  604.  
  605. }
  606.  
  607. BOOL CloseWin(WORD level)
  608. {
  609.     winopen = FALSE ;
  610.     switch(level) {
  611.     case 0:
  612.         StripWindow(xappwin) ;
  613.         CloseWindow(xappwin) ;
  614.         xappwin = NULL ;
  615.         winsig = 0 ;
  616.     case 5:
  617.     case 4:
  618.         FreeGadgets(glist) ;
  619.     case 3:
  620.         FreeVisualInfo(vi) ;
  621.     case 2:
  622.         UnlockPubScreen(NULL, ps) ;
  623.     }
  624.     return (BOOL) ( level ? FALSE : TRUE ) ;
  625. }
  626.  
  627. void ProcessWinEvents(void)
  628. {
  629. ULONG                   classe ;
  630. UWORD                   code ;
  631. struct IntuiMessage*    imsg ;
  632. struct Gadget*          gad ;
  633.  
  634.     while (imsg = GT_GetIMsg(xappwin->UserPort)) {
  635.         classe = imsg->Class ;
  636.         code = imsg->Code ;
  637.         gad = (struct Gadget *)imsg->IAddress ;
  638.         GT_ReplyIMsg(imsg) ;
  639.         switch (classe) {
  640.         case IDCMP_REFRESHWINDOW:
  641.             GT_BeginRefresh(xappwin) ;
  642.             GT_EndRefresh(xappwin, TRUE) ;
  643.             break ;
  644.         case IDCMP_GADGETUP:
  645.             switch (gad->GadgetID) {
  646.             case UPLOAD_ID:
  647.                 UploadTone() ;
  648.                 break ;
  649.             case DOWNLOAD_ID:
  650.                 DownLoadTone() ;
  651.                 break ;
  652.             case LOAD_ID:
  653.                 LoadTone() ;
  654.                 break ;
  655.             case SAVE_ID:
  656.                 SaveTone() ;
  657.                 break ;
  658.             case SETPART_ID:
  659.                 SetPart() ;
  660.                 break ;
  661.             case SETPRG_ID:
  662.                 SetPrg() ;
  663.                 break ;
  664.             case UNIT_ID:
  665.                 bData.bd_UnitNumber = code - 1 ;
  666.                 break ;
  667.             case PROGRAM_ID:
  668.                 bData.bd_ProgramNumber = code - 1 ;
  669.                 break ;
  670.             case PART_ID:
  671.                 bData.bd_PartNumber = code - 1 ;
  672.                 break ;
  673.             case TONE_ID:
  674.                 bData.bd_ToneNumber = code - 1 ;
  675.                 strncpy(tonename, bData.bd_Tone[bData.bd_ToneNumber].to_Name, 10) ;
  676.                 tonename[10] = '\0' ;
  677.                 GT_SetGadgetAttrs(tabgad[TONENAME_ID], xappwin, NULL,
  678.                     GTST_String, tonename,
  679.                     TAG_DONE) ;
  680.                 GT_SetGadgetAttrs(tabgad[SPARTIAL1_ID], xappwin, NULL,
  681.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_P12+1,
  682.                     TAG_DONE) ;
  683.                 GT_SetGadgetAttrs(tabgad[SPARTIAL2_ID], xappwin, NULL,
  684.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_P34+1,
  685.                     TAG_DONE) ;
  686.                 GT_SetGadgetAttrs(tabgad[ENVMODE_ID], xappwin, NULL,
  687.                     GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_EnvMode,
  688.                     TAG_DONE) ;
  689.                 GT_SetGadgetAttrs(tabgad[PARTIALMUTE_ID], xappwin, NULL,
  690.                     GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_PMute & (1 << bData.bd_PartialNumber),
  691.                     TAG_DONE) ;
  692.                 GT_SetGadgetAttrs(tabgad[VALUE_ID], xappwin, NULL,
  693.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_Partial[bData.bd_PartialNumber][bData.bd_ParamNumber],
  694.                     GTSL_Min,   minpartial[bData.bd_ParamNumber],
  695.                     GTSL_Max,   maxpartial[bData.bd_ParamNumber],
  696.                     TAG_DONE) ;
  697.                 break ;
  698.             case TONENAME_ID:
  699.                 strncpy(bData.bd_Tone[bData.bd_ToneNumber].to_Name, ((struct StringInfo *)gad->SpecialInfo)->Buffer, 10) ;
  700.                 PatchName() ;
  701.                 break ;
  702.             case SPARTIAL1_ID:
  703.                 bData.bd_Tone[bData.bd_ToneNumber].to_P12 = code - 1 ;
  704.                 break ;
  705.             case SPARTIAL2_ID:
  706.                 bData.bd_Tone[bData.bd_ToneNumber].to_P34 = code - 1 ;
  707.                 break ;
  708.             case ENVMODE_ID:
  709.                 bData.bd_Tone[bData.bd_ToneNumber].to_EnvMode = code ? 1 : 0 ;
  710.                 break ;
  711.             case PARTIALMUTE_ID:
  712.                 if (code)
  713.                     bData.bd_Tone[bData.bd_ToneNumber].to_PMute |= 1 << bData.bd_PartialNumber ;
  714.                 else
  715.                     bData.bd_Tone[bData.bd_ToneNumber].to_PMute &= ~(1 << bData.bd_PartialNumber) ;
  716.                 break ;
  717.             case PARTIAL_ID:
  718.                 bData.bd_PartialNumber = code - 1 ;
  719.                 GT_SetGadgetAttrs(tabgad[PARTIALMUTE_ID], xappwin, NULL,
  720.                     GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_PMute & (1 << bData.bd_PartialNumber),
  721.                     TAG_DONE) ;
  722.                 GT_SetGadgetAttrs(tabgad[VALUE_ID], xappwin, NULL,
  723.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_Partial[bData.bd_PartialNumber][bData.bd_ParamNumber],
  724.                     GTSL_Min,   minpartial[bData.bd_ParamNumber],
  725.                     GTSL_Max,   maxpartial[bData.bd_ParamNumber],
  726.                     TAG_DONE) ;
  727.                 break ;
  728.             case PARAMETER_ID:
  729.                 bData.bd_ParamNumber = code ;
  730.                 GT_SetGadgetAttrs(tabgad[VALUE_ID], xappwin, NULL,
  731.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_Partial[bData.bd_PartialNumber][bData.bd_ParamNumber],
  732.                     GTSL_Min,   minpartial[bData.bd_ParamNumber],
  733.                     GTSL_Max,   maxpartial[bData.bd_ParamNumber],
  734.                     TAG_DONE) ;
  735.                 break ;
  736.             case VALUE_ID:
  737.                 bData.bd_Tone[bData.bd_ToneNumber].to_Partial[bData.bd_PartialNumber][bData.bd_ParamNumber] = code ;
  738.                 break ;
  739.             }
  740.             break ;
  741.         case IDCMP_CLOSEWINDOW:
  742.             winopen = FALSE ;
  743.             break ;
  744.         }
  745.     }
  746. }
  747.  
  748. /* Useful C= functions */
  749.  
  750. VOID StripWindow(struct Window *win)
  751. {
  752.     Forbid();
  753.     StripIntuiMessages(win->UserPort, win);
  754.     win->UserPort = NULL;
  755.     ModifyIDCMP(win, NULL);
  756.     Permit();
  757. }
  758.  
  759. VOID    StripIntuiMessages( struct MsgPort *mp, struct Window *win )
  760.         {
  761.             struct IntuiMessage *msg;
  762.             struct Node *succ;
  763.  
  764.             msg = (struct IntuiMessage *) mp->mp_MsgList.lh_Head;
  765.  
  766.             while( succ =  msg->ExecMessage.mn_Node.ln_Succ ) {
  767.  
  768.                 if( msg->IDCMPWindow ==  win ) {
  769.  
  770.                     /* Intuition is about to free this message.
  771.                      * Make sure that we have politely sent it back.
  772.                      */
  773.                     Remove( (struct Node *)msg );
  774.  
  775.                     ReplyMsg( (struct Message *)msg );
  776.                 }
  777.  
  778.                 msg = (struct IntuiMessage *) succ;
  779.             }
  780.         }
  781.  
  782. /* Another one for a private MsgPort */
  783.  
  784. VOID    StripMessages( struct MsgPort *mp )
  785.         {
  786.             struct Message *msg;
  787.             struct Node *succ;
  788.  
  789.             msg = (struct Message *) mp->mp_MsgList.lh_Head;
  790.  
  791.             while( succ =  msg->mn_Node.ln_Succ ) {
  792.  
  793.                     Remove( (struct Node *)msg );
  794.  
  795.                     ReplyMsg( msg );
  796.  
  797.                 msg = (struct Message *) succ;
  798.             }
  799.         }
  800.  
  801.  
  802.  
  803. void UploadTone(void)
  804. {
  805. ULONG   chk ;
  806. LONG    i ;
  807.  
  808.     td[2].ti_Data = 266 ;
  809.  
  810.     midibuffer[0] = 0xF0 ;
  811.     midibuffer[1] = 0x41 ;
  812.     midibuffer[2] = bData.bd_UnitNumber ;
  813.     midibuffer[3] = 0x16 ;
  814.     midibuffer[4] = 0x12 ;
  815.     midibuffer[5] = 0x08 ;
  816.     midibuffer[6] = bData.bd_ToneNumber * 2 ;
  817.     midibuffer[7] = 0x00 ;
  818.     CopyMem(&bData.bd_Tone[bData.bd_ToneNumber], midibuffer+8, 246) ;
  819.     memset(midibuffer+254, 0, 10) ;
  820.     for (i=5, chk = 0; i<254; i++) {
  821.         chk +=midibuffer[i] ;
  822.     }
  823.     midibuffer[264] = 0x80 - (chk & 0x7F) ;
  824.     midibuffer[265]  = 0xF7 ;
  825.  
  826.     xmsg->xm_Action = XAPPACT_SENDMIDI ;
  827.     xmsg->xm_Tags = td ;
  828.     PutMsg(XAppPort, (struct Message *)xmsg);
  829.     WaitPort(replyPort) ;
  830.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  831. }
  832.  
  833. void DownLoadTone(void)
  834. {
  835. WORD i, timeout, rlen ;
  836. ULONG chk ;
  837.  
  838.     td[2].ti_Data = 13 ;
  839.     rd[2].ti_Data = 266 ;
  840.  
  841.     midibuffer[0] = 0xF0 ;
  842.     midibuffer[1] = 0x41 ;
  843.     midibuffer[2] = bData.bd_UnitNumber ;
  844.     midibuffer[3] = 0x16 ;
  845.     midibuffer[4] = 0x11 ;
  846.     midibuffer[5] = 0x08 ;
  847.     midibuffer[6] = bData.bd_ToneNumber * 2 ;
  848.     midibuffer[7] = 0x00 ;
  849.     midibuffer[8] = 0x00 ;
  850.     midibuffer[9] = 0x02 ;
  851.     midibuffer[10] = 0x00 ;
  852.     for (i=5, chk = 0; i<11; i++) {
  853.         chk +=midibuffer[i] ;
  854.     }
  855.     midibuffer[11] = 0x80 - (chk & 0x7F) ;
  856.     midibuffer[12]  = 0xF7 ;
  857.  
  858.     xmsg->xm_Action = XAPPACT_LOCKMIDI ;
  859.     xmsg->xm_Tags = td ;
  860.     PutMsg(XAppPort, (struct Message *)xmsg);
  861.     WaitPort(replyPort) ;
  862.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  863.  
  864.     xmsg->xm_Action = XAPPACT_SENDMIDI ;
  865.     xmsg->xm_Tags = td ;
  866.     PutMsg(XAppPort, (struct Message *)xmsg);
  867.     WaitPort(replyPort) ;
  868.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  869.  
  870.     memset(midibuffer, 0, 266) ;
  871.  
  872.     timeout = rlen = 0 ;
  873.  
  874.     do {
  875.         xmsg->xm_Action = XAPPACT_RECVMIDI ;
  876.         xmsg->xm_Tags = rd ;
  877.         PutMsg(XAppPort, (struct Message *)xmsg);
  878.         WaitPort(replyPort) ;
  879.         replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  880.         if (!replymsg->xm_Length) {
  881.             timeout++ ;
  882.             Delay(10) ;
  883.         }
  884.         else {
  885.             rlen += replymsg->xm_Length ;
  886.             if (rlen < 266) {
  887.                 rd[1].ti_Data = (ULONG)&midibuffer[rlen] ;
  888.                 rd[2].ti_Data = (ULONG)266-rlen ;
  889.             }
  890.         }
  891.  
  892.     } while (timeout < 3 && rlen < 266) ;
  893.  
  894.     xmsg->xm_Action = XAPPACT_UNLOCKMIDI ;
  895.     xmsg->xm_Tags = td ;
  896.     PutMsg(XAppPort, (struct Message *)xmsg);
  897.     WaitPort(replyPort) ;
  898.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  899.  
  900.     if (rlen == 266) {
  901.         CopyMem(midibuffer+8, &bData.bd_Tone[bData.bd_ToneNumber], 246) ;
  902.         strncpy(tonename, bData.bd_Tone[bData.bd_ToneNumber].to_Name, 10) ;
  903.         tonename[10] = '\0' ;
  904.         GT_SetGadgetAttrs(tabgad[TONENAME_ID], xappwin, NULL,
  905.             GTST_String, tonename,
  906.             TAG_DONE) ;
  907.         GT_SetGadgetAttrs(tabgad[SPARTIAL1_ID], xappwin, NULL,
  908.             GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_P12+1,
  909.             TAG_DONE) ;
  910.         GT_SetGadgetAttrs(tabgad[SPARTIAL2_ID], xappwin, NULL,
  911.             GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_P34+1,
  912.             TAG_DONE) ;
  913.         GT_SetGadgetAttrs(tabgad[ENVMODE_ID], xappwin, NULL,
  914.             GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_EnvMode,
  915.             TAG_DONE) ;
  916.         GT_SetGadgetAttrs(tabgad[PARTIALMUTE_ID], xappwin, NULL,
  917.             GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_PMute & (1 << bData.bd_PartialNumber),
  918.             TAG_DONE) ;
  919.         GT_SetGadgetAttrs(tabgad[VALUE_ID], xappwin, NULL,
  920.             GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_Partial[bData.bd_PartialNumber][bData.bd_ParamNumber],
  921.             GTSL_Min,   minpartial[bData.bd_ParamNumber],
  922.             GTSL_Max,   maxpartial[bData.bd_ParamNumber],
  923.             TAG_DONE) ;
  924.     }
  925.     rd[1].ti_Data = (ULONG)midibuffer ; // Reset the tag on exit
  926. }
  927.  
  928. void LoadTone(void)
  929. {
  930. BPTR fh ;
  931. LONG n ;
  932.  
  933.     if (getfile(ps, fname, pname, "#?", "Load a Tone", FALSE)) {
  934.             strcpy(filename, pname) ;
  935.             AddPart(filename, fname, 80) ;
  936.             if (fh = Open(filename, MODE_OLDFILE)) {
  937.                 n = Read(fh, &bData.bd_Tone[bData.bd_ToneNumber], 246) ;
  938.                 Close(fh) ;
  939.             }
  940.             if (n == 246) {
  941.                 PatchName() ;
  942.                 strncpy(tonename, bData.bd_Tone[bData.bd_ToneNumber].to_Name, 10) ;
  943.                 tonename[10] = '\0' ;
  944.                 GT_SetGadgetAttrs(tabgad[TONENAME_ID], xappwin, NULL,
  945.                     GTST_String, tonename,
  946.                     TAG_DONE) ;
  947.                 GT_SetGadgetAttrs(tabgad[SPARTIAL1_ID], xappwin, NULL,
  948.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_P12+1,
  949.                     TAG_DONE) ;
  950.                 GT_SetGadgetAttrs(tabgad[SPARTIAL2_ID], xappwin, NULL,
  951.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_P34+1,
  952.                     TAG_DONE) ;
  953.                 GT_SetGadgetAttrs(tabgad[ENVMODE_ID], xappwin, NULL,
  954.                     GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_EnvMode,
  955.                     TAG_DONE) ;
  956.                 GT_SetGadgetAttrs(tabgad[PARTIALMUTE_ID], xappwin, NULL,
  957.                     GTCB_Checked, bData.bd_Tone[bData.bd_ToneNumber].to_PMute & (1 << bData.bd_PartialNumber),
  958.                     TAG_DONE) ;
  959.                 GT_SetGadgetAttrs(tabgad[VALUE_ID], xappwin, NULL,
  960.                     GTSL_Level, bData.bd_Tone[bData.bd_ToneNumber].to_Partial[bData.bd_PartialNumber][bData.bd_ParamNumber],
  961.                     GTSL_Min,   minpartial[bData.bd_ParamNumber],
  962.                     GTSL_Max,   maxpartial[bData.bd_ParamNumber],
  963.                     TAG_DONE) ;
  964.             }
  965.     }
  966. }
  967.  
  968. void SaveTone(void)
  969. {
  970. BPTR fh ;
  971.  
  972.     strcpy(fname, tonename) ;
  973.     if (getfile(ps, fname, pname, "#?", "Save a Tone", TRUE)) {
  974.             strcpy(filename, pname) ;
  975.             AddPart(filename, fname, 80) ;
  976.             if (fh = Open(filename, MODE_NEWFILE)) {
  977.                 Write(fh, &bData.bd_Tone[bData.bd_ToneNumber], 246) ;
  978.                 Close(fh) ;
  979.             }
  980.     }
  981. }
  982.  
  983. void SetPart(void)
  984. {
  985. ULONG   chk ;
  986. WORD    i ;
  987.  
  988.     UploadTone() ;
  989.  
  990.     td[2].ti_Data = 12 ;
  991.     midibuffer[0] = 0xF0 ;
  992.     midibuffer[1] = 0x41 ;
  993.     midibuffer[2] = bData.bd_UnitNumber ;
  994.     midibuffer[3] = 0x16 ;
  995.     midibuffer[4] = 0x12 ;
  996.     midibuffer[5] = 0x03 ;
  997.     midibuffer[6] = 0x00 ;
  998.     midibuffer[7] = 0x10 * bData.bd_PartNumber ;
  999.     midibuffer[8] = 0x02 ;
  1000.     midibuffer[9] = bData.bd_ToneNumber ;
  1001.     for (i=5, chk = 0; i<10; i++) {
  1002.         chk +=midibuffer[i] ;
  1003.     }
  1004.     midibuffer[10] = 0x80 - (chk & 0x7F) ;
  1005.     midibuffer[11]  = 0xF7 ;
  1006.  
  1007.     xmsg->xm_Action = XAPPACT_SENDMIDI ;
  1008.     xmsg->xm_Tags = td ;
  1009.     PutMsg(XAppPort, (struct Message *)xmsg);
  1010.     WaitPort(replyPort) ;
  1011.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  1012. }
  1013.  
  1014. void SetPrg(void)
  1015. {
  1016. ULONG   chk ;
  1017. WORD    i ;
  1018.  
  1019.     UploadTone() ;
  1020.  
  1021.     td[2].ti_Data = 12 ;
  1022.     midibuffer[0] = 0xF0 ;
  1023.     midibuffer[1] = 0x41 ;
  1024.     midibuffer[2] = bData.bd_UnitNumber ;
  1025.     midibuffer[3] = 0x16 ;
  1026.     midibuffer[4] = 0x12 ;
  1027.     midibuffer[5] = 0x05 ;
  1028.     midibuffer[6] = 0x00 ;
  1029.     midibuffer[7] = 0x10 * bData.bd_ProgramNumber ;
  1030.     midibuffer[8] = 0x02 ;
  1031.     midibuffer[9] = bData.bd_ToneNumber ;
  1032.     for (i=5, chk = 0; i<10; i++) {
  1033.         chk +=midibuffer[i] ;
  1034.     }
  1035.     midibuffer[10] = 0x80 - (chk & 0x7F) ;
  1036.     midibuffer[11]  = 0xF7 ;
  1037.  
  1038.     xmsg->xm_Action = XAPPACT_SENDMIDI ;
  1039.     xmsg->xm_Tags = td ;
  1040.     PutMsg(XAppPort, (struct Message *)xmsg);
  1041.     WaitPort(replyPort) ;
  1042.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  1043. }
  1044.  
  1045. void GetProgramList(void)
  1046. {
  1047. ULONG   chk ;
  1048. WORD    i ;
  1049.  
  1050.     UploadTone() ;
  1051.  
  1052.     td[2].ti_Data = 12 ;
  1053.     midibuffer[0] = 0xF0 ;
  1054.     midibuffer[1] = 0x41 ;
  1055.     midibuffer[2] = bData.bd_UnitNumber ;
  1056.     midibuffer[3] = 0x16 ;
  1057.     midibuffer[4] = 0x12 ;
  1058.     midibuffer[5] = 0x05 ;
  1059.     midibuffer[6] = 0x00 ;
  1060.     midibuffer[7] = 0x10 * bData.bd_ProgramNumber ;
  1061.     midibuffer[8] = 0x02 ;
  1062.     midibuffer[9] = bData.bd_ToneNumber ;
  1063.     for (i=5, chk = 0; i<10; i++) {
  1064.         chk +=midibuffer[i] ;
  1065.     }
  1066.     midibuffer[10] = 0x80 - (chk & 0x7F) ;
  1067.     midibuffer[11]  = 0xF7 ;
  1068.  
  1069.     xmsg->xm_Action = XAPPACT_SENDMIDI ;
  1070.     xmsg->xm_Tags = td ;
  1071.     PutMsg(XAppPort, (struct Message *)xmsg);
  1072.     WaitPort(replyPort) ;
  1073.     replymsg = (struct XAppMsg *)GetMsg(replyPort) ;
  1074. }
  1075.  
  1076.  
  1077. struct FileRequester *InitAslFileReq(struct Screen *s, STRPTR drawer, const char *title)
  1078. {
  1079. struct FileRequester *fr = NULL ;
  1080.  
  1081.     fr = (struct FileRequester *)AllocAslRequestTags(ASL_FileRequest,
  1082.         ASLFR_Screen,           s,
  1083.         ASLFR_RejectIcons,      TRUE,
  1084.         ASLFR_TitleText,        title,
  1085.         ASLFR_InitialDrawer,    drawer,
  1086.         TAG_DONE) ;
  1087.     return fr ;
  1088. }
  1089.  
  1090.  
  1091.  
  1092. BOOL getfile(struct Screen *s, STRPTR name, STRPTR drawer, STRPTR pat, const char *title, BOOL savemode)
  1093. {
  1094. struct FileRequester *fr ;
  1095. BOOL retval = FALSE ;
  1096.  
  1097.     if (fr = InitAslFileReq(s, drawer, title)) {
  1098.         if (AslRequestTags(fr,
  1099.             ASLFR_InitialFile,      name,
  1100.             ASLFR_InitialPattern,   pat,
  1101.             ASLFR_DoSaveMode,       savemode,
  1102.             ASLFR_DoPatterns,       TRUE,
  1103.             TAG_DONE)) {
  1104.             strcpy(name, fr->fr_File) ;
  1105.             strcpy(drawer, fr->fr_Drawer) ;
  1106.             retval = TRUE ;
  1107.         }
  1108.         FreeAslRequest(fr) ;
  1109.     }
  1110.     return retval ;
  1111. }
  1112.  
  1113. void PatchName(void)
  1114. {
  1115. LONG n ;
  1116. UBYTE c ;
  1117.  
  1118.     n = 0 ;
  1119.     do {
  1120.         c = bData.bd_Tone[bData.bd_ToneNumber].to_Name[n] ;
  1121.         if ((c < 32) || (c > 127 ))
  1122.             bData.bd_Tone[bData.bd_ToneNumber].to_Name[n] = ' ' ;
  1123.         n++ ;
  1124.     } while (c && (n<10)) ;
  1125.     while(n<10) {
  1126.         bData.bd_Tone[bData.bd_ToneNumber].to_Name[n++] = ' ' ;
  1127.     }
  1128. }
  1129.